#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "Element.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class InputPin;
class Property;
class QualifierValue;

/// <summary>
/// LinkEndData
/// LinkEndData is an Element that identifies on end of a link to be read or written
/// by a LinkAction. As a link (that is not a link object) cannot be passed as a
/// runtime value to or from an Action, it is instead identified by its end objects
/// and qualifier values, if any. A LinkEndData instance provides these values for a
/// single Association end.
/// </summary>
class UMLMODEL_EXPORT LinkEndData : public Element {

public: // Constructors and destructors
    explicit LinkEndData(const QString& umlType="uml::LinkEndData");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
    /// <summary>
    /// allPins
    /// Returns all the InputPins referenced by this LinkEndData. By default this
    /// includes the value and qualifier InputPins, but subclasses may override the
    /// operation to add other InputPins.
    /// </summary>
    virtual shared_ptr<vector<InputPin>> allPins() const;

public: // Properties
    /// <summary>
    /// end getter
    /// The Association end for which this LinkEndData specifies values.
    /// </summary>
    shared_ptr<Property> end() const;

    /// <summary>
    /// end setter
    /// The Association end for which this LinkEndData specifies values.
    /// </summary>
    void setEnd(shared_ptr<Property> value);

    /// <summary>
    /// qualifiers getter
    /// A set of QualifierValues used to provide values for the qualifiers of the end.
    /// </summary>
    vector<shared_ptr<QualifierValue>>& qualifiers();

    /// <summary>
    /// value getter
    /// The InputPin that provides the specified value for the given end. This InputPin
    /// is omitted if the LinkEndData specifies the "open" end for a ReadLinkAction.
    /// </summary>
    shared_ptr<InputPin> value() const;

    /// <summary>
    /// value setter
    /// The InputPin that provides the specified value for the given end. This InputPin
    /// is omitted if the LinkEndData specifies the "open" end for a ReadLinkAction.
    /// </summary>
    void setValue(shared_ptr<InputPin> value);

private: // Fields
    /// <summary>
    /// end
    /// The Association end for which this LinkEndData specifies values.
    /// </summary>
    shared_ptr<Property> end_;

    /// <summary>
    /// qualifiers
    /// A set of QualifierValues used to provide values for the qualifiers of the end.
    /// </summary>
    vector<shared_ptr<QualifierValue>> qualifiers_;

    /// <summary>
    /// value
    /// The InputPin that provides the specified value for the given end. This InputPin
    /// is omitted if the LinkEndData specifies the "open" end for a ReadLinkAction.
    /// </summary>
    shared_ptr<InputPin> value_;

};

} // namespace uml
